Most modern computer systems, especially multiprocessor systems, will run a plurality of user or application tasks concurrently. Each of these tasks, and the operating system itself, generate input/output (I/O) requests as the programs run. Usually these I/O requests are uncorrelated, which means that the requests have no specific relationship to each other between tasks. It is of considerable importance to handle the I/O requests efficiently and effectively so as to not unduly restrict the data throughput or processing capabilities of such multi-task computer systems.
In a computer system, there is at least one central processor, a main memory, and one or more I/O channels connected to I/O devices. These elements are connected within this processor-memory complex for doing input/output data communications. In many prior systems, the connection between the processor and the I/O channel is a fixed connection. If there is only one processor, as in a uniprocessor computer system, the fixed connections between the I/O devices and the processor do not create any restriction, because the single processor which controls all of the I/O devices can only proceed with one function at a time. In multiprocessor systems, those which involve multiple central processors, the fixed connection of each I/O channel to one processor can create problems. If the program running on one processor needs to access a device on an I/O channel connected to a different processor, the communication can occur, but only over a circuitous route. Such circuitous routes generally create inefficient data transfers and unnecessary data movement within system memory. The inefficiencies result primarily from the fixed connectivity of each I/O channel to a specific processor.
Data communication in a multiprocessor system sometimes requires the movement of data from one memory location to another memory location as a result of the fixed connectivity. It is usually inefficient to move data from one memory location to another memory location, because such memory movements do not contribute to meaningful data throughput or data processing efficiency. Moving data between a peripheral device and memory in either direction is acceptable, but moving data between different locations in main memory should generally be avoided if possible.
One common method of handling I/O requests in prior art computer systems is to utilize interrupts for accomplishing input/output functions. However, the nature of most modern processors (including the entire current generation of high performance microprocessors) is that interrupts are handled only at the expense of consuming relatively large amounts of time and processing resources. Accordingly, minimizing the occurrence of interrupts is quite important. Minimizing the occurrence of interrupts is also quite difficult with such prior art computer systems.
In many prior art multi-task multiprocessor systems, the I/O drivers tend to be somewhat complex in nature and it tends to be difficult to maintain their operating routines. This problem is further compounded if the I/O drivers and the processors to which they are connected in a fixed manner utilize specific operating codes applicable only to particular processor and the particular connected I/O drivers. The lack of commonality in such arrangements adds to the complexity of the system and generally involves inefficiency of data processing and data throughput.
In the past, some computer systems have used I/O processors or peripheral processors to essentially attempt to partition the I/O control functions between the I/O processors and the central processors of the system. Some of these I/O processing systems have worked reasonably well, but far more of them have actually slowed down data throughput and resulted in worse efficiency due to the added overhead in communicating between the central processor and the I/O processor.